
/**
 * Content: Synchronized用法-锁定实例对象
 * --------------------------------------------------
 * Java基础——Synchronized用法: https://juejin.cn/post/6844903705523798029
 */

public class java_1113_synchronized {
    public static void main(String[] args) {

        // Synchronized用法
        System.out.println("--------------------Synchronized用法--------------------");

        // 创建线程: 通过同一个实例创建的, synchronized 才会有效果 (因为是同一把锁)
//        MyThread4 myThread4 = new MyThread4();
//        Thread thread1 = new Thread(myThread4, "thread1");   // 这两个线程是使用同一个实例创建的
//        Thread thread2 = new Thread(myThread4, "thread2");

        // 创建线程: 不是通过同一个实例创建的线程, 则 synchronized 不会产生效果 (各自拥有各自的锁, 所以不会互斥)
        Thread thread1 = new Thread(new MyThread4(), "thread1");   // 这两个线程是使用同一个实例创建的
        Thread thread2 = new Thread(new MyThread4(), "thread2");

        // 启动线程
        thread1.start();
        thread2.start();

    }
}

// 一、Synchronized 修饰代码块
class MyThread4 implements Runnable {

    // synchronized 锁住的对象, 则同一个实例创建的线程访问 synchronized 修饰的代码时会互斥
    //      若 object 用 static 修饰, 则 object 属于类变量, 则不同实例创建的线程访问 synchronized 修饰的代码时也会互斥
    static Object object = new Object();

    private int count;

    public MyThread4() {
        count = 0;
    }

    @Override
    public void run() {
        // 同步代码块中锁定的是当前实例对象
        synchronized(object) {            // 一个线程执行结束, 另一个线程才能进入执行
            for (int i = 0; i < 10; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ":" + (count++));
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
